//
//  SketchServer.java
//  SketchServer
//
//  Created by Brian Hinch on 9/4/08.
//  Copyright (c) 2008 Tellart. All rights reserved.
//
//	For information on setting Java configuration information, including 
//	setting Java properties, refer to the documentation at
//		http://developer.apple.com/techpubs/java/java.html
//

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.swing.Timer;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.URL;
import java.net.NetworkInterface;
import java.net.InetAddress;
import java.net.Inet4Address;
import javax.imageio.*;

import javax.swing.*;
import javax.swing.border.*;

//import javax.comm.*;
import gnu.io.*;
//import Serialio.SerialPortLocal;

import java.util.TooManyListenersException;

import com.apple.eawt.*;

public class SketchServer extends JFrame implements MouseMotionListener {

    //protected Timer ioPackMonitorTimer;

	//private Font font = new Font("sans serif", +Font.BOLD, 36);
	protected ResourceBundle resbundle;
	protected AboutBox aboutBox;
	protected PrefPane prefs;
	private Application fApplication = Application.getApplication();
	protected Action startServerAction, stopServerAction, /*publishSkecthAction,*/ /*monitorIOPackAction,*/
        ioPackSerialPortComboAction, sketchServerNetworkInterfaceComboAction, toggleIOPackPollingAction, toggleIOPackSimulationAction,
		toggleHandheldFlowControlAction;
	static final JMenuBar mainMenuBar = new JMenuBar();	
	protected JMenu serverMenu; 
    //protected JLabel sketchServerStatus;
    protected JLabel errorIOPackSerial, errorSketchServerNetwork, errorIOPackWireless, errorSketchServerWireless;
    protected JLabel serverStatus, wirelessIOPack, wirelessNetwork;
    protected JLabel[] monitorIOPackInputs, monitorIOPackOutputs;
	
	private boolean simulateIOPack = false;
    private boolean dataRouterStarting = false;
    private boolean dataRouterStopping = false;
    
    private final static String IMAGE_PATH_BACKGROUND = "/gui_background.png";
    private final static int IMAGE_WIDTH_BACKGROUND = 320;
    private final static int IMAGE_HEIGHT_BACKGROUND = 436;
    
    private final static String IMAGE_PATH_WIRELESS_ICON = "/gui_connection.png";
    private final static int IMAGE_WIDTH_WIRELESS_ICON = 47;
    private final static int IMAGE_HEIGHT_WIRELESS_ICON = 47;
    
    private final static String IMAGE_PATH_ERROR_ICON = "/gui_error.png";
    private final static int IMAGE_WIDTH_ERROR_ICON = 47;
    private final static int IMAGE_HEIGHT_ERROR_ICON = 47;
    
    private SketchDataRouterConfiguration routerConfiguration = new SketchDataRouterConfiguration();
	
	public SketchServer()  {
        super("");
        
        //defaults
        SketchDataRouter.getInstance().setIOPackPollingEnabled(true);
        SketchDataRouter.getInstance().setHandheldFlowControlEnabled(true);
    }
    
    public void setUpGUI() throws IOException {
		// The ResourceBundle below contains all of the strings used in this
		// application.  ResourceBundles are useful for localizing applications.
		// New localities can be added by adding additional properties files.
		resbundle = ResourceBundle.getBundle ("strings", Locale.getDefault());
		setTitle(resbundle.getString("frameConstructor"));
        
        final JPanel cp = new JPanel(null);
        setContentPane(cp);
        
        cp.setBorder(new CenteredBackgroundBorder(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_BACKGROUND))));
        
		createActions();
		addMenus();
        addWindowControls();

        clearErrorIcons();
        setUIFromRouterState();
        
		setSize(IMAGE_WIDTH_BACKGROUND, IMAGE_HEIGHT_BACKGROUND);
        setResizable(false);

		if (fApplication != null) fApplication.setEnabledPreferencesMenu(true);
		if (fApplication != null) fApplication.addApplicationListener(new com.apple.eawt.ApplicationAdapter() {
			public void handleAbout(ApplicationEvent e) {
                                if (aboutBox == null) {
                                    aboutBox = new AboutBox();
                                }
                                about(e);
                                e.setHandled(true);
			}
			public void handleOpenApplication(ApplicationEvent e) {
			}
			public void handleOpenFile(ApplicationEvent e) {
			}
			public void handlePreferences(ApplicationEvent e) {
                                if (prefs == null) {
                                    prefs = new PrefPane();
                                }
				preferences(e);
			}
			public void handlePrintFile(ApplicationEvent e) {
			}
			public void handleQuit(ApplicationEvent e) {
				quit(e);
			}
		});
		
		this.addMouseMotionListener(this);
		
        updateUILater();
        
		setVisible(true);
	}

	public void about(ApplicationEvent e) {
		aboutBox.setResizable(false);
		aboutBox.setVisible(true);
	}

	public void preferences(ApplicationEvent e) {
		prefs.setResizable(false);
		prefs.setVisible(true);
	}

	public void quit(ApplicationEvent e) {	
		System.exit(0);
	}

	public void createActions() {
		int shortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

		//Create actions that can be used by menus, buttons, toolbars, etc.
		startServerAction = new StartServerActionClass( resbundle.getString("startItem"),
											KeyStroke.getKeyStroke(KeyEvent.VK_N, shortcutKeyMask) );
		stopServerAction = new StopServerActionClass( resbundle.getString("stopItem"),
											KeyStroke.getKeyStroke(KeyEvent.VK_W, shortcutKeyMask) );
        /*
		publishSkecthAction = new PublishSkecthActionClass( resbundle.getString("publishSketchButton"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_F12, shortcutKeyMask) );
											*/
        /*
		monitorIOPackAction = new MonitorIOPackActionClass( resbundle.getString("monitorIOPackButton"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_M, shortcutKeyMask) );
											*/
        ioPackSerialPortComboAction = new IOPackSerialPortComboActionClass("");
        sketchServerNetworkInterfaceComboAction = new SketchServerNetworkInterfaceComboActionClass("");
        toggleIOPackPollingAction = new ToggleIOPackPollingActionClass ( resbundle.getString("pollIOPackCheckbox"));
		toggleIOPackSimulationAction = new ToggleIOPackSimulationActionClass ( resbundle.getString("simulateIOPackCheckbox"));
		toggleHandheldFlowControlAction = new ToggleHandheldFlowControlActionClass ( resbundle.getString("handheldFlowControl"));
	}
    
    public void setUIFromRouterState() {
    
        if (dataRouterStopping) {
            startServerAction.setEnabled(false);
            stopServerAction.setEnabled(false);
            toggleIOPackPollingAction.setEnabled(false);
            toggleIOPackSimulationAction.setEnabled(false);
            toggleHandheldFlowControlAction.setEnabled(false);
            sketchServerNetworkInterfaceComboAction.setEnabled(false);
            ioPackSerialPortComboAction.setEnabled(false);
            serverStatus.setText(resbundle.getString("serverStatusStopping"));
            serverStatus.setVisible(!errorSketchServerNetwork.isVisible());
        
        } else if (dataRouterStarting) {
            startServerAction.setEnabled(false);
            stopServerAction.setEnabled(false);
            toggleIOPackPollingAction.setEnabled(false);
            toggleIOPackSimulationAction.setEnabled(false);
            toggleHandheldFlowControlAction.setEnabled(false);
            sketchServerNetworkInterfaceComboAction.setEnabled(false);
            ioPackSerialPortComboAction.setEnabled(false);
            serverStatus.setText(resbundle.getString("serverStatusStarting"));
            serverStatus.setVisible(!errorSketchServerNetwork.isVisible());
        
        } else if (SketchDataRouter.getInstance().isStarted()) {
            startServerAction.setEnabled(false);
            stopServerAction.setEnabled(true);
            toggleIOPackPollingAction.setEnabled(false);
            toggleIOPackSimulationAction.setEnabled(false);
            toggleHandheldFlowControlAction.setEnabled(false);
            //publishSkecthAction.setEnabled(true);
            //monitorIOPackAction.setEnabled(true);
            sketchServerNetworkInterfaceComboAction.setEnabled(false);
            ioPackSerialPortComboAction.setEnabled(false);
            
            //wirelessIOPack.setVisible(true);
            //wirelessNetwork.setVisible(true);
            
            //set the server status label
            serverStatus.setText(resbundle.getString("serverStatusWaiting"));
            serverStatus.setVisible(!wirelessNetwork.isVisible() && !errorSketchServerNetwork.isVisible());
            
        } else {
            startServerAction.setEnabled(true);
            stopServerAction.setEnabled(false);
            toggleIOPackPollingAction.setEnabled(true);
            toggleIOPackSimulationAction.setEnabled(true);
            toggleHandheldFlowControlAction.setEnabled(true);
            //publishSkecthAction.setEnabled(false);
            //monitorIOPackAction.setEnabled(false);
            sketchServerNetworkInterfaceComboAction.setEnabled(true);
            ioPackSerialPortComboAction.setEnabled(true);
            
            wirelessIOPack.setVisible(false);
            wirelessNetwork.setVisible(false);
            serverStatus.setText(resbundle.getString("serverStatusStopped"));
            serverStatus.setVisible(!errorSketchServerNetwork.isVisible());
            
            //set the monitor labels
            for (int i = 0; i < monitorIOPackInputs.length; i++)
                monitorIOPackInputs[i].setText("   ");
            for (int i = 0; i < monitorIOPackOutputs.length; i++)
                monitorIOPackOutputs[i].setText("   ");
            
            //set the server status label
            //sketchServerStatus.setText(resbundle.getString("serverStatusStopped"));
        }
    } //setUIFromRouterState
	
	public void addMenus() {

		serverMenu = new JMenu(resbundle.getString("serverMenu"));
		serverMenu.add(new JMenuItem(startServerAction));
		serverMenu.add(new JMenuItem(stopServerAction));
		mainMenuBar.add(serverMenu);

		setJMenuBar (mainMenuBar);
	}
    
    public void addWindowControls() throws IOException {
    
        Container cp = getContentPane();
        
        /*** Add buttons ***/
        JButton button;
        
        //start server button
        button = new JButton(startServerAction);
        button.setBounds(77, 199, 80, 22);
        cp.add(button);
        
        //stop server button
        button = new JButton(stopServerAction);
        button.setBounds(158, 199, 80, 22);
        cp.add(button);
        
        //publish sketch button
		/*
        button = new JButton(publishSkecthAction);
        button.setBounds(678, 121, 150, 22);
        cp.add(button);
		*/
        
        JCheckBox cb = new JCheckBox(toggleIOPackPollingAction);
        cb.setSelected(SketchDataRouter.getInstance().getIOPackPollingEnabled());
        cb.setBounds(179, 34, 230, 25);
        cp.add(cb);
		
		cb = new JCheckBox(toggleIOPackSimulationAction);
		cb.setSelected(false);
		cb.setBounds(179, 56, 230, 25);
		cp.add(cb);
		
		cb = new JCheckBox(toggleHandheldFlowControlAction);
		cb.setSelected(SketchDataRouter.getInstance().getHandheldFlowControlEnabled());
		cb.setBounds(186, 363, 230, 25);
		cp.add(cb);
        
        /*** Add monitor labels ***/
        Font fnt = new Font("SansSerif", Font.PLAIN, 9);
        int xStart = 14;
        int yStart = 14;
        int xIncrement = 20;
        int yIncrement = 16;
        
        monitorIOPackInputs = new JLabel[SketchProtocol.SET_MESSAGE_NUM_VALUES];
        int y = yStart;
        int x = xStart;
        for (int i = 0; i < monitorIOPackInputs.length; i++) {
            monitorIOPackInputs[i] = new JLabel();
            monitorIOPackInputs[i].setFont(fnt);
            monitorIOPackInputs[i].setBounds(x, y, 40, 22);
            cp.add(monitorIOPackInputs[i]);
            
            x += xIncrement;
            //if ((x + xIncrement + xIncrement) >= IMAGE_WIDTH_BACKGROUND) {
            if (i == 5) {
                y+= yIncrement;
                x = xStart;
            }
        }
        
        y+= yIncrement + 4;
        x = xStart;
        monitorIOPackOutputs = new JLabel[SketchProtocol.SET_MESSAGE_NUM_VALUES];
        for (int i = 0; i < monitorIOPackOutputs.length; i++) {
            monitorIOPackOutputs[i] = new JLabel();
            monitorIOPackOutputs[i].setFont(fnt);
            monitorIOPackOutputs[i].setBounds(x, y, 40, 22);
            cp.add(monitorIOPackOutputs[i]);
            
            x += xIncrement;
            //if ((x + xIncrement + xIncrement) >= IMAGE_WIDTH_BACKGROUND) {
            if (i == 5) {
                y+= yIncrement;
                x = xStart;
            }
        }
        
        /*** Add error labels ***/
        
        errorIOPackSerial = new JLabel(resbundle.getString("errorIOPackSerial"));
        errorIOPackSerial.setToolTipText(resbundle.getString("errorIOPackSerial"));
        errorIOPackSerial.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_ERROR_ICON))));
        errorIOPackSerial.setBounds(135, 86, IMAGE_WIDTH_ERROR_ICON, IMAGE_WIDTH_ERROR_ICON);
        cp.add(errorIOPackSerial);

        errorIOPackWireless = new JLabel(resbundle.getString("errorIOPackWireless"));
        errorIOPackWireless.setToolTipText(resbundle.getString("errorIOPackWireless"));
        errorIOPackWireless.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_ERROR_ICON))));
        errorIOPackWireless.setBounds(135, 86, IMAGE_WIDTH_ERROR_ICON, IMAGE_WIDTH_ERROR_ICON);
        cp.add(errorIOPackWireless);
        
        errorSketchServerNetwork = new JLabel(resbundle.getString("errorSketchServerNetwork"));
        errorSketchServerNetwork.setToolTipText(resbundle.getString("errorSketchServerNetwork"));
        errorSketchServerNetwork.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_ERROR_ICON))));
        errorSketchServerNetwork.setBounds(135, 280, IMAGE_WIDTH_ERROR_ICON, IMAGE_WIDTH_ERROR_ICON);
        cp.add(errorSketchServerNetwork);

        errorSketchServerWireless = new JLabel(resbundle.getString("errorSketchServerWireless"));
        errorSketchServerWireless.setToolTipText(resbundle.getString("errorSketchServerWireless"));
        errorSketchServerWireless.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_ERROR_ICON))));
        errorSketchServerWireless.setBounds(135, 280, IMAGE_WIDTH_ERROR_ICON, IMAGE_WIDTH_ERROR_ICON);
        cp.add(errorSketchServerWireless);
        
        /*** Add info labels ***/
        //sketchServerStatus = new JLabel(resbundle.getString("serverStatusInitializing"));
        //sketchServerStatus.setBounds(76, 183, 200, 22);
        //cp.add(sketchServerStatus);

        serverStatus = new JLabel(resbundle.getString("serverStatusStopped"));
        serverStatus.setBounds(130, 280, 200, 22);
        cp.add(serverStatus);
        
        wirelessIOPack = new JLabel(resbundle.getString("wirelessIOPack"));
        wirelessIOPack.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_WIRELESS_ICON))));
        wirelessIOPack.setBounds(135, 86, IMAGE_WIDTH_WIRELESS_ICON, IMAGE_HEIGHT_WIRELESS_ICON);
        cp.add(wirelessIOPack);
        
        wirelessNetwork = new JLabel(resbundle.getString("wirelessNetwork"));
        wirelessNetwork.setIcon(new ImageIcon(ImageIO.read(SketchServer.class.getResource(IMAGE_PATH_WIRELESS_ICON))));
        wirelessNetwork.setBounds(135, 280, IMAGE_WIDTH_WIRELESS_ICON, IMAGE_HEIGHT_WIRELESS_ICON);
        cp.add(wirelessNetwork);
        
        /*** Config drop-down lists ***/
        JComboBox combo;
        String[] items;
        
        items = getIOPackSerialPortComboItems();
        routerConfiguration.setIOPackSerialPort(items[0]);
        combo = new JComboBox(items);
        combo.setAction(ioPackSerialPortComboAction);
        combo.setBounds(40, 150, 240, 25);
        cp.add(combo);
        
        items = getSketchServerNetworkInterfaceComboItems();
        routerConfiguration.setSketchServerNetworkInterface(items[0]);
        combo = new JComboBox(items);
        combo.setAction(sketchServerNetworkInterfaceComboAction);
        combo.setBounds(40, 240, 240, 25);
        cp.add(combo);
    
    } //addWindowControls
    
    
    /*
     * returns an array of serial port strings suitable for adding to a combo box
     *
     */
    private String[] getIOPackSerialPortComboItems() {
		System.out.println("Getting valid Serial keys...");
		String[] keys = new String[0];
		ArrayList keyList = new ArrayList();

		CommPortIdentifier portId;
		SerialPort testPort;
        String portName;
        boolean addedDisable = false;
        for (int pass = 0; pass < 2; pass++) {
            java.util.Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
            while ( portEnum.hasMoreElements() ) 
            {
                try {
                    portId = (CommPortIdentifier) portEnum.nextElement();
                    if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                        portName = portId.getName();
                        
                        if (((pass == 0) && portName.toLowerCase().startsWith("/dev/cu.usbserial-"))
                            ||
                            ((pass == 1) && !portName.toLowerCase().startsWith("/dev/cu.usbserial-"))
                        ) {
                            
                            System.out.println("Found " + portName);
                            
                            //testPort = (SerialPort) portId.open("getIOPackSerialPortComboItems Detection", IOPackSerialController.PORT_OPEN_TIMEOUT);
                            //testPort.close();
                            keyList.add(portName);
                        }
                    }
                } catch (Exception e) { System.err.println(e); }
            }//enumeration
            if (((keyList.size() == 0) || (pass > 0)) && !addedDisable ) {
                keyList.add(IOPackSerialController.DISABLED_INTERFACE);
                addedDisable = true;
            }
        }
        
		keys = (String[])keyList.toArray(keys);
		return keys;
		
    } //getIOPackSerialPortComboItems
    
    
    /*
     * returns an array of network interface strings suitable for adding to a combo box
     *
     */
    private String[] getSketchServerNetworkInterfaceComboItems() {
		ArrayList validIpList = new ArrayList();
		try{
            for (int pass = 0; pass < 2; pass++) {
                Enumeration e = NetworkInterface.getNetworkInterfaces();
                System.out.println("Found Network Interfaces");
                while (e.hasMoreElements()){
                    NetworkInterface n = (NetworkInterface)e.nextElement();
                    Enumeration e2 = n.getInetAddresses();
                    System.out.println("Interface: "+n.getName());
                    while (e2.hasMoreElements()){
                        InetAddress i = (InetAddress)e2.nextElement();
                        System.out.println("\tHas address:"+i.toString()+" IP4 (will be used?): "+(i instanceof Inet4Address));
                        if (i instanceof Inet4Address) {
                            if (((pass == 0) && n.getName().toLowerCase().equals("en1")) || ((pass > 0) && !n.getName().toLowerCase().equals("en1")))
                                validIpList.add(i.getHostAddress());
                        }
                    }
                }
            }
            
		}catch(Exception e){ e.printStackTrace(); }
        
        validIpList.add(SketchSocketController.DISABLED_INTERFACE);

		return (String[])validIpList.toArray(new String[0]);
    } //getSketchServerNetworkInterfaceComboItems
    
    
	public void paint(Graphics g) {
		super.paint(g);
	}
    
    public void clearErrorIcons() {
        errorIOPackSerial.setVisible(false);
        errorSketchServerNetwork.setVisible(false);
        errorIOPackWireless.setVisible(false);
        errorSketchServerWireless.setVisible(false);
    } //clearErrorIcons
	
	/*
	 * from MouseMotionListener
	 */
	public void mouseEntered( MouseEvent e ){}
	public void mouseExited( MouseEvent e ){}
	public void mouseDragged( MouseEvent e ){}
	public void mouseMoved( MouseEvent e ){
		//feed test data to the router
		if (simulateIOPack) SketchDataRouter.getInstance().setManualSimulatedIOPackData(e.getX());
	}
	
	public class StartServerActionClass extends AbstractAction {
		public StartServerActionClass(String text, KeyStroke shortcut) {
			super(text);
			putValue(ACCELERATOR_KEY, shortcut);
		}
		public void actionPerformed(ActionEvent e) {
			System.out.println("Start...");

            dataRouterStarting = true;
            dataRouterStopping = false;
            clearErrorIcons();
            setUIFromRouterState();
            
            new Thread(new Runnable() {
                public void run() {
                    //start the router
                    try {
                    
                        SketchDataRouter.getInstance().start(routerConfiguration);
                        //updateUILater();
                        
                    } catch (NoSuchPortException nspe) {
                        errorIOPackSerial.setVisible(true);
                        System.err.println(nspe.getLocalizedMessage());
                        nspe.printStackTrace(System.err);
                    } catch (TooManyListenersException tmle) {
                        errorIOPackSerial.setVisible(true);
                        System.err.println(tmle.getLocalizedMessage());
                        tmle.printStackTrace(System.err);
                    } catch (PortInUseException piue) {
                        errorIOPackSerial.setVisible(true);
                        System.err.println(piue.getLocalizedMessage());
                        piue.printStackTrace(System.err);
                    } catch (IOException ioe) {
                        errorIOPackSerial.setVisible(true);
                        System.err.println(ioe.getLocalizedMessage());
                        ioe.printStackTrace(System.err);
                    } catch (Exception ex) {
                        System.err.println(ex.getLocalizedMessage());
                        ex.printStackTrace(System.err);
                    }
                    
                    dataRouterStopping = false;
                    dataRouterStarting = false;
                    setUIFromRouterState();
                }
            }).start();
            
            this.setEnabled(false);
        }
	}
    
    public void updateUILater() {
    
        /*
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
        */
        new Timer(100, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {

                //System.out.println("updateUILater");
                
                try {
                    wirelessIOPack.setVisible(SketchDataRouter.getInstance().isIOPackConnectionActive());
                    wirelessNetwork.setVisible(SketchDataRouter.getInstance().isHandheldConnected());
                    //serverStatus.setVisible(SketchDataRouter.getInstance().isStarted() && !wirelessNetwork.isVisible() && !errorSketchServerNetwork.isVisible());
                    
                    if (SketchDataRouter.getInstance().isStarted()) {
                        int[] inValues = SketchDataRouter.getInstance().monitorIOPackInputs;
                        int[] outValues = SketchDataRouter.getInstance().monitorIOPackOutputs;
                        
                        //System.out.println("-------------------------------");
                        for (int i = 0; ((i < monitorIOPackInputs.length) && (i < inValues.length)); i++) {
                            monitorIOPackInputs[i].setText("" + inValues[i]);
                            //System.out.println("in "+i+": "+inValues[i]);
                        }
                        
                        for (int i = 0; ((i < monitorIOPackOutputs.length) && (i < outValues.length)); i++)
                            monitorIOPackOutputs[i].setText("" + outValues[i]);
                    }
                    
                } catch (Exception e) {
                    System.err.println(e.getLocalizedMessage());
                    e.printStackTrace(System.err);
                }
                
                //updateUILater();
            }
        }).start();
    }

	public class StopServerActionClass extends AbstractAction {
		public StopServerActionClass(String text, KeyStroke shortcut) {
			super(text);
			putValue(ACCELERATOR_KEY, shortcut);
		}
		public void actionPerformed(ActionEvent e) {
			System.out.println("Stop...");

            dataRouterStarting = false;
            dataRouterStopping = true;
            setUIFromRouterState();
            
            new Thread(new Runnable() {
                public void run() {

                    //stop the router
                    System.out.println("Begin stopping...");
                    SketchDataRouter.getInstance().stop();
                    System.out.println("Done stopping.");
                    dataRouterStopping = false;
                    dataRouterStarting = false;
                    setUIFromRouterState();
                }
            }).start();

            this.setEnabled(false);
		}
	}
    
	public class PublishSkecthActionClass extends AbstractAction {
		public PublishSkecthActionClass(String text, KeyStroke shortcut) {
			super(text);
			putValue(ACCELERATOR_KEY, shortcut);
		}
		public void actionPerformed(ActionEvent e) {
			System.out.println("Publish sketch...");
		}
	}
	public class MonitorIOPackActionClass extends AbstractAction {
		public MonitorIOPackActionClass(String text, KeyStroke shortcut) {
			super(text);
			putValue(ACCELERATOR_KEY, shortcut);
		}
		public void actionPerformed(ActionEvent e) {
			System.out.println("Monitor IOPack...");
		}
	}
    public class ToggleIOPackPollingActionClass extends AbstractAction {
        public ToggleIOPackPollingActionClass(String text) {
            super(text);
        }
		public void actionPerformed(ActionEvent e) {
			System.out.println("ToggleIOPackPollingActionClass... ");
			SketchDataRouter.getInstance().setIOPackPollingEnabled(((JCheckBox)e.getSource()).isSelected());
		}
	}
	public class ToggleIOPackSimulationActionClass extends AbstractAction {
        public ToggleIOPackSimulationActionClass(String text) {
            super(text);
        }
		public void actionPerformed(ActionEvent e) {
			System.out.println("ToggleIOPackSimulationActionClass... ");
			//simulateIOPack = ((JCheckBox)e.getSource()).isSelected();
			SketchDataRouter.getInstance().setAutomaticSimulatedIOPackData(((JCheckBox)e.getSource()).isSelected());
		}
	}
	public class ToggleHandheldFlowControlActionClass extends AbstractAction {
		public ToggleHandheldFlowControlActionClass(String text) {
            super(text);
        }
		public void actionPerformed(ActionEvent e) {
			System.out.println("ToggleHandheldFlowControlActionClass... ");
			SketchDataRouter.getInstance().setHandheldFlowControlEnabled(((JCheckBox)e.getSource()).isSelected());
		}
	}
		
    public class IOPackSerialPortComboActionClass extends AbstractAction {
		public IOPackSerialPortComboActionClass(String text) {
			super(text);
		}
		public void actionPerformed(ActionEvent e) {
            String id = (String)((JComboBox)e.getSource()).getSelectedItem();
            routerConfiguration.setIOPackSerialPort(id);
			System.out.println("IOPackSerialPortComboAction... " + id);
		}
    }
    public class SketchServerNetworkInterfaceComboActionClass extends AbstractAction {
		public SketchServerNetworkInterfaceComboActionClass(String text) {
			super(text);
		}
		public void actionPerformed(ActionEvent e) {
            String id = (String)((JComboBox)e.getSource()).getSelectedItem();
            routerConfiguration.setSketchServerNetworkInterface(id);
			System.out.println("SketchServerNetworkInterfaceComboActionClass... " + id);
		}
    }

	 public static void main(String args[]) {
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    new SketchServer().setUpGUI();
                } catch (Exception e) {
                    System.err.println(e.getLocalizedMessage());
                    e.printStackTrace(System.err);
                }
            }
        });
	 } //main

} //SketchServer class
